package lbframework.bean.calendar;

import com.toedter.calendar.JCalendar;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JPopupMenu;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import lbframework.classe.Util;
import lbframework.bean.panel.LBPanel;

public class LBCalendar extends LBPanel implements ActionListener, PropertyChangeListener {

    protected JCalendar jCalendar;
    protected boolean dateSelected;
    private ChangeListener changeListener;
    private boolean obrigatorio = false;

    public LBCalendar() {
        initComponents();

        jCalendar = new JCalendar();
        jCalendar.getDayChooser().addPropertyChangeListener("day", this);
        jCalendar.getDayChooser().setAlwaysFireDayProperty(true);

        btnData.addActionListener(this);

        popup = new JPopupMenu() {

            private static final long serialVersionUID = -6078272560337577761L;

            @Override
            public void setVisible(boolean b) {
                Boolean isCanceled = (Boolean) getClientProperty("JPopupMenu.firePopupMenuCanceled");
                if (b || (!b && dateSelected) || ((isCanceled != null) && !b && isCanceled.booleanValue())) {
                    super.setVisible(b);
                }
            }
        };

        popup.setLightWeightPopupEnabled(true);
        popup.add(jCalendar);

        //corrige problema do foco no combo mes
        changeListener = new ChangeListener() {

            boolean hasListened = false;

            public void stateChanged(ChangeEvent e) {
                if (hasListened) {
                    hasListened = false;
                    return;
                }
                if (popup.isVisible() && LBCalendar.this.jCalendar.getMonthChooser().getComboBox().hasFocus()) {
                    MenuElement[] me = MenuSelectionManager.defaultManager().getSelectedPath();
                    MenuElement[] newMe = new MenuElement[me.length + 1];
                    newMe[0] = popup;
                    for (int i = 0; i < me.length; i++) {
                        newMe[i + 1] = me[i];
                    }
                    hasListened = true;
                    MenuSelectionManager.defaultManager().setSelectedPath(newMe);
                }
            }
        };
        MenuSelectionManager.defaultManager().addChangeListener(changeListener);
    }

    private void abrirCalendario() throws Exception {
        int x = btnData.getWidth() - (int) popup.getPreferredSize().getWidth();
        int y = btnData.getY() + btnData.getHeight();

        Calendar calendar = Calendar.getInstance();

        if (!txtData.getClipText().equals("")) {
            if (Util.isDataValida(txtData.getText())) {
                calendar.setTime(new SimpleDateFormat("dd/MM/yyyy").parse(txtData.getText()));
            }
        }

        jCalendar.setCalendar(calendar);
        popup.show(btnData, x, y);
    }

    @Override
    public synchronized void addMouseListener(MouseListener l) {
        txtData.addMouseListener(l);
    }

    @Override
    public synchronized void addKeyListener(KeyListener l) {
        txtData.addKeyListener(l);
    }

    @Override
    public synchronized void addFocusListener(FocusListener l) {
        txtData.addFocusListener(l);
    }

    @Override
    public void requestFocus() {
        txtData.requestFocus();
    }

    @Override
    public void transferFocus() {
        txtData.transferFocus();
    }

    public void actionPerformed(ActionEvent e) {
        try {
            abrirCalendario();

        } catch (Exception ex) {
            Util.exibirMensagemErro(ex, "Atenção");
        }
    }

    public void propertyChange(PropertyChangeEvent evt) {
        try {
            if (evt.getPropertyName().equals("day")) {
                if (popup.isVisible()) {
                    dateSelected = true;
                    popup.setVisible(false);

                    txtData.setText(new SimpleDateFormat("dd/MM/yyyy").format(jCalendar.getCalendar().getTime()));
                    txtData.requestFocus();
                    txtData.transferFocus();
                }
            }
        } catch (Exception ex) {
            Util.exibirMensagemErro(ex, "Atenção");
        }
    }

    public String getText() {
        return txtData.getText();
    }

    public void setText(String i_text) {
        txtData.setText(i_text);
    }

    public String getClipText() {
        return txtData.getClipText();
    }

    @Override
    public void setEnabled(boolean enabled) {
        txtData.setEnabled(enabled);
        btnData.setEnabled(enabled);

        setObrigatorio(obrigatorio);
    }

    @Override
    public boolean isEnabled() {
        return txtData.isEnabled();
    }

    public void setDataInicio(String dataInicio) {
        txtData.setDataInicio(dataInicio);
    }

    @Override
    public void setNextFocusableComponent(Component aComponent) {
        txtData.setNextFocusableComponent(aComponent);
    }

    public boolean isObrigatorio() {
        return obrigatorio;
    }

    public void setObrigatorio(boolean obrigatorio) {
        this.obrigatorio = obrigatorio;

        if (txtData.isEnabled()) {
            if (obrigatorio) {
                txtData.setBackground(Util.COR_OBRIGATORIO);
            } else {
                txtData.setBackground(UIManager.getColor("TextField.background"));
            }
        } else {
            txtData.setBackground(UIManager.getColor("TextField.disabledBackground"));
        }
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        popup = new javax.swing.JPopupMenu();
        txtData = new lbframework.bean.textField.LBTextField();
        btnData = new lbframework.bean.button.LBButton();

        setBorder(null);

        txtData.setMascara("Data");
        txtData.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                txtDataKeyPressed(evt);
            }
        });

        btnData.setIcon(new javax.swing.ImageIcon(getClass().getResource("/lbframework/bean/calendar/calendar16.png"))); // NOI18N
        btnData.setToolTipText("Abrir calendário (F6)");
        btnData.setFocusable(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(txtData, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnData, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(txtData, javax.swing.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE)
                .addComponent(btnData, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void txtDataKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtDataKeyPressed
        try {
            if (evt.getKeyCode() == KeyEvent.VK_F6) {
                abrirCalendario();
            }

        } catch (Exception ex) {
            Util.exibirMensagemErro(ex, "Atenção");
        }
    }//GEN-LAST:event_txtDataKeyPressed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private lbframework.bean.button.LBButton btnData;
    private javax.swing.JPopupMenu popup;
    private lbframework.bean.textField.LBTextField txtData;
    // End of variables declaration//GEN-END:variables

    public void setConsultaData(Method consultaData) {
        txtData.setConsultaData(consultaData);
    }
}
